package zl.applet.block;
/**
* 分别对应对7种模型的28种状态
*条形
*11110000 00000000  4096 + 8192 + 16384 + 32768 = 61440
*10001000 10001000  8 + 128 + 2048 + 32768 = 34952
*
*'7'型
*10001000 11000000  64 + 128 + 2048 + 32768 = 35008
*11101000 00000000  2048 + 8192 + 16384 + 32768 = 59392
*11000100 01000000  64 + 1024 + 16384 + 32768 = 50240
*00101110 00000000  512 + 1024 + 2048 + 8192 = 11776
*
*反'7'型
*01000100 11000000  64 + 128 + 1024 + 16384 = 17600
*10001110 00000000	512 + 1024 + 2048 + 32768 = 36352
*11001000 10000000	128 + 2048 + 16384 + 32768 = 51328
*11100010 00000000	512 + 8192 + 16384 + 32768 = 57856
*
*'Z'型
*01001100 10000000	128 + 1024 + 2048 + 16384 = 19584
*11000110 00000000	512 + 1024 + 16384 + 32768 = 50688
*
*反'Z'型
*10001100 01000000	64 + 1024 + 2048 + 32768 = 35904
*01101100 00000000	1024 + 2048 + 8192 + 16384 = 27648
*
*'T'型
*11100100 00000000	1024 + 8192 + 16384 + 32768 = 58368
*01001100 01000000	64 + 1024 + 2048 + 16384 = 19520
*01001110 00000000	512 + 1024 + 2048 + 16384 = 19968
*10001100 10000000	128 + 1024 + 2048 + 32768 = 35968
*
*方形
*11001100 00000000	1024 + 2048 + 16384 + 32768 = 52224
*
*被与'&'数   
*10000000 00000000  32768
*/

//方块类
public class Block extends Thread
{
	public static final int BOXES_ROWS = 4;		//方块的行
	public static final int BOXES_COLS = 4;		//方块的列
	public static final int[][] STYLES = {
		{61440,34952,61440,34952},     //条形方块
		{35008,59392,50240,11776},     //'7'型方块
		{17600,36352,51328,57856},     //反'7'型方块
		{19584,50688,19584,50688},     //'Z'型方块
		{35904,27648,35904,27648},     //反'Z'型方块
		{58368,19520,19968,35968},     //'T'型方块
		{52224,52224,52224,52224}      //方形方块
	};
	public static final int KEY = 32768;
	private Canvas canvas;			//方块所处面板
	private Box[][] boxes;			//方块所包含的格子
	private int style,x,y;
	private boolean pausing,moving = true;
	private int level;

	//构造方法
	public Block(int style, int x, int y,int level,Canvas canvas)
	{
		this.style = style;
		this.x = x;
		this.y = y;
		this.level = level;
		this.canvas = canvas;
		int key = Block.KEY;
		this.boxes = new Box[Block.BOXES_ROWS][Block.BOXES_COLS];
		for(int i = 0; i < this.boxes.length; i++)
		{
			for(int j = 0; j < this.boxes[i].length; j++)
			{
				//按照样式初始化方块
				this.boxes[i][j] = new Box((this.style & key) != 0);
				key >>= 1;
			}
		}
	}

	public int getStyle()
	{
		return this.style;
	}
	public void setPausing(boolean pausing)
	{
		this.pausing = pausing;
	}
	public boolean getPausing()
	{
		return this.pausing;
	}
	public void setLevel(int level)
	{
		this.level = level;
	}

	//方块往下移动一行的时候。走过的路要擦除掉
	public void erase()
	{
		for(int i = 0; i < this.boxes.length; i++)
		{
			for(int j = 0; j < this.boxes[i].length; j++)
			{
				if(this.boxes[i][j].getIsColor())
				{
					Box box = this.canvas.getBox(this.x + i - Block.BOXES_ROWS,this.y + j);
					if(box == null)
						continue;
					box.setIsColor(false);
				}
			}
		}
	}

	//方块往下移动一行
	public void display()
	{
		for(int i = 0; i < this.boxes.length; i++)
		{
			for(int j = 0; j < this.boxes[i].length; j++)
			{
				if(this.boxes[i][j].getIsColor())
				{
					Box box = this.canvas.getBox(this.x + i - Block.BOXES_ROWS,this.y + j);
					if(box == null)
						continue;
					box.setIsColor(true);
				}
			}
		}
	}

	public void run()
	{
		while(moving)
		{
			try
			{
				Thread.sleep(200 + (BlockGame.MAXLEVEL - this.level) * 30);
			}
			catch (InterruptedException e)
			{
				e.printStackTrace();
			}
			if(!this.pausing)
			{
				this.moving = (this.moveTo(this.x + 1,this.y)&&this.moving);
			}
		}
	}

	public void moveLeft()
	{
		this.moveTo(this.x,this.y - 1);
	}

	public void moveRight()
	{
		this.moveTo(this.x,this.y + 1);
	}

	public void moveDown()
	{
		this.moveTo(this.x + 1,this.y);
	}

	//方块能否移动
	public boolean isMoveable(int newRow,int newCol)
	{
		this.erase();
		for(int i = 0; i < this.boxes.length; i++)
		{
			for(int j = 0; j < this.boxes[i].length; j++)
			{
				if(this.boxes[i][j].getIsColor())
				{
					Box box = this.canvas.getBox(newRow + i - Block.BOXES_ROWS,newCol + j);
					if(box == null)
					{
						if(newCol + j >= this.canvas.getCols() || newCol + j < 0 || 
							newRow + i - Block.BOXES_ROWS >= this.canvas.getRows())
						{
							this.display();
							return false;
						}
					}
					else if(box.getIsColor())
					{
						this.display();
						return false;
					}
				}
			}
		}
		this.display();
		return true;
	}

	//方块移动
	public synchronized boolean moveTo(int newRow,int newCol)
	{
		if(!this.isMoveable(newRow,newCol) || !this.moving)
		{
			return false;
		}
		this.erase();
		this.x = newRow;
		this.y = newCol;
		this.display();
		this.canvas.repaint();
		return true;
	}
	
	//方块能否改变样式
	public boolean isTurnable(int style)
	{
		this.erase();
		int key = Block.KEY;
		for(int i = 0; i < this.boxes.length; i++)
		{
			for(int j = 0; j < this.boxes[i].length; j++)
			{
				if((style & key) != 0)
				{
					Box box = this.canvas.getBox(this.x + i - Block.BOXES_ROWS,this.y + j);
					if(box == null)
					{
						if(this.y + j >= this.canvas.getCols() || this.y + j < 0
							|| this.x + i - Block.BOXES_ROWS >= this.canvas.getRows())
						{
							this.display();
							return false;
						}
					}
					else if(box.getIsColor())
					{
						this.display();
						return false;
					}
				}
				key >>= 1;
			}
		}
		this.display();
		return true;
	}

	//改变方块样式
	public boolean turnTo(int style)
	{
		if(!this.isTurnable(style))
		{
			return false;
		}
		this.erase();
		this.style = style;
		int key = Block.KEY;
		for(int i = 0; i < this.boxes.length; i++)
		{
			for(int j = 0; j < this.boxes[i].length; j++)
			{
				this.boxes[i][j].setIsColor((this.style & key) != 0);
				key >>= 1;
			}
		}
		this.display();
		this.canvas.repaint();
		return true;
	}
}